package de.gameduell.framework.util {
	import flash.net.navigateToURL;
	import flash.net.URLRequest;

	import de.gameduell.framework.debug.Debug;

	import flash.display.DisplayObjectContainer;
	import flash.external.ExternalInterface;
	import flash.system.Security;

	/**
	 * Provides some usefull methods for String manipulations.
	 */
	public class Tools {
		
		/**
		 * This function fill up a number with zeros
		 * example: 1 becomes 0001
		 * 
		 * @param number the number to fill up with zeros
		 * @param digits the number of digits you want to have
		 * 
		 * @return the given number filled up with zeros
		 */
		public static function zeroize(number:Number, digits:uint):String {
			var result:String = String(number);
			digits--;
			if(number < 1) {
				result = "0";
				for(var i:uint = 0;i < digits;i++) {
					result = "0" + result;
				} 
				return result;
			}
			while((number / (Math.pow(10, digits)) < 1)) {
				digits--;
				result = "0" + result;
			}
			return result;
		}
		
		/**
		 * removes spaces when they occur more than once.
		 */
		public static function eatDoubleSpaces(aString:String):String{
			var splitString:Array = aString.split(" ");
			var result:Array = new Array();
			for(var i:* in splitString){
				if(splitString[i] != ""){
					result.push(splitString[i]);
				}
			}
			return result.join(" ");
		}

		/**
		 * enable doubleClick for a DisplayObject and its children
		 */
		public static function enableDoubleClick(aDisplayObject:DisplayObjectContainer):void {
			aDisplayObject.doubleClickEnabled = true;
			for (var i:int = 0;i < aDisplayObject.numChildren; i++) {
				if (aDisplayObject.getChildAt(i) is DisplayObjectContainer) {
					var displayObject:DisplayObjectContainer = aDisplayObject.getChildAt(i) as DisplayObjectContainer;
					enableDoubleClick(displayObject);
				}
			}
		}

		/**
		 * Doing a ltrim() and rtrim() at once.
		 * Trimming a string means cutting all whitespaces on both ends of a String.
		 * 
		 * @param input		a string to be trimmed
		 */
		public static function trim(input:String):String {
			return ltrim(rtrim(input));
		}

		/**
		 * Trimming all whitespaces on the left side of a String.
		 * 
		 * @param input		a string to be left-trimmed
		 */
		public static function ltrim(input:String):String {
			var size:Number = input.length;
			for(var i:Number = 0;i < size; i++) {
				if(input.charCodeAt(i) > 32) {
					return input.substring(i);
				}
			}
			return "";
		}

		/**
		 * Trimming all whitespaces on the right side of a String.
		 * 
		 * @param input		a string to be right-trimmed
		 */
		public static function rtrim(input:String):String {
			var size:Number = input.length;
			for(var i:Number = size;i > 0; i--) {
				if(input.charCodeAt(i - 1) > 32) {
					return input.substring(0, i);
				}
			}
			return "";
		}
		
		/**
		 * convert to number with fixed precission, limit differences on network sync
		 * @param	value
		 * @return fixed point Number
		 */
		public static function toFixedNumber(value:Number):Number {
			return Number(value.toFixed(3));
		} 

		/**
		 * Doing the same like Math.abs() - calculate an absolute value of a number.
		 * 
		 * @see Math.abs()
		 * @param value		a number to absolute
		 */
		public static function abs(value:Number):Number {
			return value < 0 ? -value : value;
		}
		
		/**
		 * call javascript function flashtrace
		 * @param params:String parameter to be passed to the JS function
		 */		
		public static function traceToFrontend(params:String):void {
			callJavaScript("flashtrace", params);
		}

		/**
		 * call javascript function
		 * @param params:String parameter to be passed to the JS function
		 * @param method:String JS function to call
		 */	
		public static function callJavaScript(funcName:String, ...args):void {
			try {
				if(Security.sandboxType != Security.LOCAL_WITH_FILE) {
					if(ExternalInterface.available) {
						var argArray:Array = new Array();
						argArray.push(funcName);
						for (var j:int = 0;j < args.length; j++) {
							argArray.push(args[j]);
						}
						var f:Function = ExternalInterface.call;
						f.apply(null, argArray);  
					} else {
						Debug.trace("callJS: ExternalInterface is not available ", Debug.WARNING);
						for (var i:uint = 0;i < args.length; i++) {
							args[i] = "'" + args[i] + "'";
						}
						var argsStr:String = args.join(",");
						var str:String = "javascript:" + funcName + "(" + argsStr + ")";	
						var req:URLRequest = new URLRequest(str);
						navigateToURL(req, "_self");
					}
				} else {
					Debug.trace("callJS: call JS function via ExternalInterface blocked because sandboxType is Security.LOCAL_WITH_FILE ", Debug.WARNING);
				}
			} catch (er:Error) {
				Debug.trace("callJS: unable to call JS function via ExternalInterface -> error: " + er, Debug.ERROR);
			}
		}
	}
}